﻿

module	core.hgevector;

private import  	core.hgeall;
private import 	std.c.math;


/*
** Fast 1.0/sqrtf(float) routine
*/
	union convertor
        {
          int 		intPart;
          float 	floatPart;
        } 
		
float InvSqrt(float x)
{
	convertor	co;

        co.floatPart = x;
        co.intPart = 0x5f3759df - (co.intPart >> 1);
        return co.floatPart*(1.5f - 0.4999f*x*co.floatPart*co.floatPart);
}

struct hgeVector
{
public:
	float	x,y;

static	hgeVector 	opCall(float _x, float _y)	{ 
						hgeVector vv;
						vv.x=_x; vv.y=_y; 
						return vv;
						}
static	hgeVector 	opCall()					{ 
						hgeVector vv;
						vv.x=0.0f; vv.y=0.0f; 
						return vv;
						}

	hgeVector	opSub   ( hgeVector v) { return hgeVector(x-v.x, y-v.y); }
	hgeVector	opAdd ( hgeVector v) { return hgeVector(x+v.x, y+v.y); }
	hgeVector	opMul (float scalar) { return hgeVector(x*scalar, y*scalar); }
	hgeVector	opSubAssign ( hgeVector v) { x-=v.x; y-=v.y; return *this; }
	hgeVector	opAddAssign ( hgeVector v) { x+=v.x; y+=v.y; return *this; }
	hgeVector	opMulAssign (float scalar) { x*=scalar; y*=scalar; return *this; }
	hgeVector	opNeg () { return hgeVector(-x, -y); }
	bool		opEquals( hgeVector v) { return (x==v.x && y==v.y); }
//	bool		op != ( hgeVector v) { return (x!=v.x || y!=v.y); }

	float		Dot( hgeVector v)  { return x*v.x + y*v.y; }
	hgeVector	Normalize() { float rc=InvSqrt(Dot(*this)); x*=rc; y*=rc; return *this; }
	float		Length()  { return sqrtf(Dot(*this)); }
	float		Angle( hgeVector* 	v=null )
	{
		if(v)
		{
			hgeVector 	s=*this;
			hgeVector	t=*v;

			s.Normalize(); t.Normalize();
			return acosf(s.Dot(t));
		}
		else return atan2f(y, x);
	}

	
	hgeVector	Rotate(float a)
	{
		hgeVector v;

		v.x=x*cosf(a) - y*sinf(a);
		v.y=x*sinf(a) + y*cosf(a);

		x=v.x; y=v.y;

		return *this;
	}

	
}

/* 
inline hgeVector opMul * ( hgeVector v, float s) { return hgeVector(s*v.x, s*v.y); }
inline hgeVector opMul * (float s,  hgeVector v) { return hgeVector(s*v.x, s*v.y); }
inline float op ^ ( hgeVector v,  hgeVector &u) { return v.Angle(&u); }
inline float op % ( hgeVector v,  hgeVector &u) { return v.Dot(&u); } */

